﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.UI;
using log4net;

namespace TemplateFoundation.WebControls
{
    /// <summary>
    /// Provides extension methods for controls
    /// </summary>
    public static class Extensions
    {
        /// <summary>
        /// Renders a control to a string
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static string RenderToString(this Control control)
        {
            var sb = new StringBuilder();

            using (var sw = new StringWriter(sb))
            {
                using (var tw = new HtmlTextWriter(sw))
                {
                    control.RenderControl(tw);    
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// Used to identify which control triggered a postback
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        public static Control GetPostBackControl(this Page page)
        {
            string controlName = page.Request.Params.Get("__EVENTTARGET");

            if (!string.IsNullOrEmpty(controlName))
            {
                // Postback caused by control using JavaScript and __doPostBack()
                return page.FindControl(controlName);
            }

            try
            {
                return GetChildControls(page).FirstOrDefault(c => c != null && (c is System.Web.UI.WebControls.Button || c is EPiServer.UI.WebControls.ToolButton));
            }
            catch (NullReferenceException)
            {
                LogManager.GetLogger("GetPostBackControl").Warn("Null reference exception occured while trying to retrieve control that caused postback");

                return null;
            }
        }

        /// <summary>
        /// Returns all child controls recursively
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        private static IEnumerable<Control> GetChildControls(Control control)
        {
            var controlsToReturn = new List<Control>();

            if (control.Controls != null && control.Controls.Count>0)
            {
                foreach (Control c in control.Controls)
                {
                    controlsToReturn.Add(c); // Add the parent

                    controlsToReturn.AddRange(GetChildControls(c)); // Add its children
                }
            }

            return controlsToReturn;
        }
    }
}
